/*****************************************************************************/
/**
 *  @file   ParticleSend.h
 *  @author Allan Lorant, Naohisa Sakamoto
 */
/*----------------------------------------------------------------------------
 *
 *  Copyright (c) Visualization Laboratory, Kyoto University.
 *  All rights reserved.
 *  See http://www.viz.media.kyoto-u.ac.jp/kvs/copyright/ for details.
 *
 *  $Id$
 */
/*****************************************************************************/
#ifndef PARTICLE_SEND_H_INCLUDE
#define PARTICLE_SEND_H_INCLUDE

#include <cstring>
#include <iostream>
#include <kvs/PointObject>
#include <flowvr/module.h>
#include "InterfaceBase.h"


namespace ParticleSend
{

/*===========================================================================*/
/**
 *  @brief  Interface class for pixel send module.
 */
/*===========================================================================*/
class Interface : public InterfaceBase
{
    typedef InterfaceBase SuperClass;

private:

    flowvr::OutputPort* m_particle_port;

public:

    Interface()
    {
        // Declare user defined ports :
        m_particle_port = new flowvr::OutputPort( "particleOut" );

        std::vector<flowvr::Port*> ports;
        ports.push_back( m_particle_port );

        if ( SuperClass::init( ports ) )
        {
            std::cout << "Can't initialize flowVR module !" << std::endl;
        }
    }

    ~Interface()
    {
        if ( m_particle_port ) delete m_particle_port;
    }

    bool send( const kvs::PointObject* object )
    {
        // Byte size of each data
        const size_t coords_size = object->coords().byteSize();
        const size_t colors_size = object->colors().byteSize();
        const size_t normals_size = object->normals().byteSize();
        const size_t data_size = coords_size + colors_size + normals_size;

        // Allocate the messages
        flowvr::MessageWrite particle;
        particle.data = InterfaceBase::alloc( data_size );
        if ( particle.data.empty() )
        {
            std::cout << "[Send]Alloc error framebuffer" << std::endl;
            return false;
        }

        // Copy the data into the messages
        flowvr::ubyte* pcoords = particle.data.writeAccess();
        flowvr::ubyte* pcolors = pcoords + coords_size;
        flowvr::ubyte* pnormals = pcolors + colors_size;
#if ( KVS_VERSION_MAJOR == 1 )
        std::memcpy( pcoords, object->coords().pointer(), coords_size );
        std::memcpy( pcolors, object->colors().pointer(), colors_size );
        std::memcpy( pnormals, object->normals().pointer(), normals_size );
#elif ( KVS_VERSION_MAJOR == 2 )
        std::memcpy( pcoords, object->coords().data(), coords_size );
        std::memcpy( pcolors, object->colors().data(), colors_size );
        std::memcpy( pnormals, object->normals().data(), normals_size );
#endif

        // Send the messages
        InterfaceBase::put( "particleOut", particle );
        particle.data.clear();

        return true;
    }
};

} // end of namespace ParticleSend

#endif // PARTICLE_SEND_H_INCLUDE
